/**
 * Parse string to Product object
 * String format:code;Type;name;*;
 * Different Type has different attributes:
 * Type=E: Equipment, its special attributes:pricePerUnit
 * Type=L: License, its special attributes:serviceFee;annualLicenseFee
 * Type=C: Consultation, its special attributes:consultantPersonCode;hourlyFee
 */
package data.converter.parser;

import java.util.ArrayList;
import java.util.HashMap;

import data.converter.model.Consultation;
import data.converter.model.Equipment;
import data.converter.model.License;
import data.converter.model.Person;
import data.converter.model.Product;

public class ParserToProduct {

	private String[] names = {
			"productCode","type", "name"
	};
	
	private HashMap<String,String> mapping = new HashMap<String, String>();
	private ArrayList<Person> personList;
	
	public void setPersonList(ArrayList<Person> personList) {
		this.personList = personList;
	}
	
	/**
	 * 
	 * @param strValue
	 * @return product
	 * According to type value, dispatch to corresponding method 
	 */
	public Product getProduct(String strValue) {
		String[] items = strValue.split(";");
		Product product = new Product();
		for(int i=0; i < names.length; i++) {
			mapping.put(names[i], items[i] == null ? "" : items[i]);
		}
		product.setName(mapping.get("name"));
		product.setProductCode(mapping.get("productCode"));
		char type = mapping.get("type").charAt(0);
		product.setType(type);
		String[] specialItems = new String[items.length - 3];
		for(int i = 0, j = names.length; i < specialItems.length; i++, j++) {
			specialItems[i] = items[j];
		}
		switch(type){
		case 'E':
			return converterToEquipment(product, specialItems);
		case 'L':
			return converterToLicense(product,specialItems);
		case 'C':
			return converterToConsultant(product,specialItems);
		}
		return null;
	}
	
	public Product converterToEquipment(Product product, String[] items) {
		Equipment equipment = new Equipment(product);
		if(items.length > 0){
			equipment.setPricePerUnit(items[items.length - 1] != null
					? Double.parseDouble(items[items.length - 1]) : 0);
		}
		return equipment;
	}
	
	public Product converterToLicense(Product product, String[] items) {
		License license = new License(product);
		if(items.length == 2) {
			license.setFee(items[0] != null ? Double.parseDouble(items[0]) : 0);
			license.setAnnualCost(items[1] != null ? Double.parseDouble(items[1]) : 0);
		}
		if(1 == items.length) {
			license.setFee(items[0] != null ? Double.parseDouble(items[0]) : 0);
		}
		return license;
	}
	
	public Product converterToConsultant(Product product, String[] items) {
		Consultation consultant = new Consultation(product);
		if(items.length == 2) {
			String consultantCode = items[0] != null ? items[0] : "";
			consultant.setConsultant(searchPerson(consultantCode));
			consultant.setHourlyFee(items[1] != null ? Double.parseDouble(items[1]) : 0);
		}
		if (1 == items.length) {
			consultant.setHourlyFee(items[0] != null ? Double.parseDouble(items[0]) : 0);
		}
		return consultant;
	}
	
	private Person searchPerson(String personCode) {
		if(personList == null || personList.isEmpty()) {
			return null;
		}
		for(Person person: personList) {
			if(personCode.equals(person.getPersonCode())) {
				return person;
			}
		}
		return null;
	}
}
